/*
 * Copyright Hundsun Technologies Inc. All Rights Reserved.
 */

package contract

import (
	"github.com/golang/protobuf/proto"
	"hundsun.com/hsl/hschain/common/types"
	pbcom "hundsun.com/hsl/hschain/protos/common"
	"hundsun.com/hsl/hschain/store/db"
)

// EventDB 合约事件存储对象
type EventDB struct {
	get db.DatabaseGet
}

// NewContractEventDB new ContractEventDB
func NewContractEventDB(get db.DatabaseGet) *EventDB {
	return &EventDB{get: get}
}

// GetContractEvent get ContractEvent from eventKey and address
func (c *EventDB) GetContractEvent(eventKey string, address string) (*pbcom.ContractEvent, error) {
	if c.get == nil {
		return nil, types.ErrNotFound
	}
	v, err := c.get.Get(GenContractEventKey(eventKey, address))
	if err != nil {
		return nil, err
	}
	ctEvent := &pbcom.ContractEvent{}
	err = proto.Unmarshal(v, ctEvent)
	if err != nil {
		return nil, err
	}
	return ctEvent, nil
}

// GetContractEvents get GetContractEvents from eventKeys and contractName
func (c *EventDB) GetContractEvents(eventkeys []string, contractName string) ([]*pbcom.ContractEvent, error) {
	if c.get == nil {
		return nil, types.ErrNotFound
	}
	keys := make([][]byte, len(eventkeys))
	for i, key := range eventkeys {
		keys[i] = GenContractEventKey(key, contractName)
	}
	values, err := c.get.Gets(keys)
	if err != nil {
		return nil, err
	}
	var ctEvents []*pbcom.ContractEvent
	for _, v := range values {
		ctEvent := &pbcom.ContractEvent{}
		err = proto.Unmarshal(v, ctEvent)
		if err != nil {
			continue
		}
		ctEvents = append(ctEvents, ctEvent)
	}
	return ctEvents, nil
}

// EventKV from ContractStatus to kv
func EventKV(ctStat *pbcom.ContractStatus) (*pbcom.KeyValue, error) {
	kv := &pbcom.KeyValue{}
	kv.Key = GenContractEventKey(ctStat.Key, ctStat.Address)
	v, err := proto.Marshal(ctStat)
	if err != nil {
		return nil, err
	}
	kv.Value = v
	return kv, nil
}

// GenContractEventKey generate ContractEvent key
func GenContractEventKey(contractName string, key string) []byte {
	return []byte(db.NamespaceContractEvent + contractName + key)
}
